package framework.storage;

import framework.config.FileConfig;
import lombok.Getter;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * 使用本地存储的文件存储实现
 */
public class FileStorageLocal implements FileStorage {
    private static final int BUFFER_SIZE = 1 * 1024 * 1024;

    @Getter
    private FileConfig config;

    public FileStorageLocal(FileConfig config) {
        this.config = config;
    }

    @Override
    public String[] compressionPathStarts() {
        return this.config.getCompressPathStarts();
    }

    @Override
    public long save(InputStream inputStream, String filePath, boolean compression) throws IOException {
        filePath = this.buildFilePath(filePath);
        if (compression) {
            filePath += ".gz";
        }

        //
        File file = new File(filePath);

        //父目录检查
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();

        //
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            if (compression) {
                try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream)) {
                    long rows = IOUtils.copy(inputStream, gzipOutputStream, BUFFER_SIZE);
                    gzipOutputStream.finish();
                    return rows;
                }
            }
            long rows = IOUtils.copy(inputStream, outputStream, BUFFER_SIZE);
            outputStream.flush();
            return rows;
        }
    }

    @Override
    public InputStream getStream(String filePath, boolean compression) throws IOException {
        filePath = this.buildFilePath(filePath);
        if (compression) {
            filePath += ".gz";
            return new GZIPInputStream(new FileInputStream(filePath));
        }
        return new FileInputStream(filePath);
    }

    @Override
    public void delete(String filePath, boolean compression) throws IOException {
        filePath = this.buildFilePath(filePath);
        if (compression) {
            filePath += ".gz";
        }
        new File(filePath).delete();
    }

    @Override
    public long length(String filePath, boolean compression) throws IOException {
        filePath = this.buildFilePath(filePath);
        if (compression) {
            filePath += ".gz";
        }
        File file = new File(filePath);
        if (!file.exists()) {
            return -1L;
        }
        return file.length();
    }

    private String buildFilePath(String filePath) {
        if (filePath.charAt(0) == '/' || filePath.charAt(0) == '\\')
            filePath = filePath.substring(1);
        return this.config.getStoragePath() + File.separator + filePath;
    }
}
